/**
  ******************************************************************************
  * @file    IAP/IAP_Main/Src/menu.c
  * @author  MCD Application Team

  * @brief   This file provides the software which contains the main menu routine.
  *          The main menu gives the options of:
  *             - downloading a new binary file,
  *             - uploading internal flash memory,
  *             - executing the binary file already loaded
  *             - configuring the write protection of the Flash sectors where the
  *               user loads his binary file.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2017 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */

/** @addtogroup STM32F4xx_IAP_Main
  * @{
  */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "common.h"
#include "menu.h"
#include "ymodem.h"
#include "usart.h"
#include "iap.h"
#include "log.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/

uint32_t FlashProtection = 0;
uint8_t aFileName[FILE_NAME_LENGTH];

/* Private function prototypes -----------------------------------------------*/
void SerialDownload(void);
void SerialUpload(void);

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Download a file via serial port
  * @param  None
  * @retval None
  */
void SerialDownload(void)
{
    uint8_t number[11] = {0};
    uint32_t size = 0;
    COM_StatusTypeDef result;

    LOG_DEBUG("\r\nWaiting for the file to be sent ... (press 'a' to abort)\r\n");
    result = Ymodem_Receive( &size );
    if (result == COM_OK)
    {
        LOG_DEBUG("\r\nProgramming Completed Successfully!\r\n");
        LOG_DEBUG("--------------------------------\r\n");
        LOG_DEBUG("    Name: %s\r\n", aFileName);
        LOG_DEBUG("    Size: %d Bytes\r\n", size);
        LOG_DEBUG("--------------------------------\r\n");
    }
    else if (result == COM_LIMIT)
    {
        LOG_DEBUG("\r\nThe image size is higher than the allowed space memory!\r\n");
    }
    else if (result == COM_DATA)
    {
        LOG_DEBUG("\r\nVerification failed!\r\n");
    }
    else if (result == COM_ABORT)
    {
        LOG_DEBUG("\r\nAborted by user.\r\n");
    }
    else
    {
        LOG_DEBUG("\r\nFailed to receive the file!\r\n");
    }
}
/**
  * @brief  Upload a file via serial port.
  * @param  None
  * @retval None
  */
void SerialUpload(void)
{
    uint8_t status = 0;

    LOG_DEBUG("\r\nSelect Receive File and Do not press any key!\r\n");

    HAL_UART_Receive(USART1, &status, 1, RX_TIMEOUT);
    if ( status == CRC16)
    {
        /* Transmit the flash image through ymodem protocol */
        status = Ymodem_Transmit((uint8_t*)0x8000000, (const uint8_t*)"Image.bin", 32768);

        if (status != 0)
        {
            LOG_DEBUG("\r\nError Occurred while Transmitting File\r\n");
        }
        else
        {
            LOG_DEBUG("\r\nFile uploaded successfully\r\n");
        }
    } else {
        LOG_DEBUG("\r\nEnding receive Because received char is not 'C'\r\n");
    }
}

/**
  * @brief  Display the Main Menu on HyperTerminal
  * @param  None
  * @retval None
  */
void Main_Menu(void)
{
    uint8_t key = 0;
    uint8_t cnt = 0;
    uint8_t ret = 0;
	/**/
    cnt = 1;
DISMENU:
    LOG_DEBUG("\r\n=================== Main Menu ============================\r\n");
    LOG_DEBUG("    Download image to the internal Flash ------------ 1\r\n");
    LOG_DEBUG("    Upload image from the internal Flash ------------ 2\r\n");
    LOG_DEBUG("    Execute the loaded application ------------------ 3\r\n");
    LOG_DEBUG("==========================================================\r\n");
    while (1)
    {
        /*cnt = second(s)*/
        while(cnt > 0) {
            ret = HAL_UART_Receive(USART1, &key, 1, 1000);
            if(ret != HAL_TIMEOUT) {
                break;
            } else {
                LOG_DEBUG("You have (%d) second(s) to key a value!\r", cnt);
            }
            cnt--;
        }
        if(ret == HAL_TIMEOUT) {
            iap_load_app();
        }
        switch (key)
        {
        case '1' :
            /* Download user application in the Flash */
            SerialDownload();
            cnt = 15;
            goto DISMENU;
            break;
        case '2' :
            SerialUpload();
            cnt = 15;
            goto DISMENU;
            break;
        case '3' :
            LOG_DEBUG("\r\nStart app program execution......\r\n");
            iap_load_app();
            break;
        default:
            LOG_DEBUG("\r\nInvalid Number! ==> The number should be either 1, 2 or 3\r");
            break;
        }
    }
}

/**
  * @}
  */
